package de.joergviola.mobj.client.database;

import java.io.Serializable;
import java.util.Arrays;
import java.util.logging.Logger;

import com.google.code.gwt.database.client.SQLTransaction;
import com.google.code.gwt.database.client.StatementCallback;

import de.joergviola.mobj.shared.Entity;
import de.joergviola.mobj.shared.Schema;
import de.joergviola.mobj.shared.UnknownEntityException;

public class Update<T extends Serializable> {

	private static final Logger log = Logger.getLogger("Update");
	private final Entity<T> entity;
	private final T t;
	private Schema schema;

	public Update(Schema schema, Entity<T> entity, T t) {
		this.schema = schema;
		this.entity = entity;
		this.t = t;
	}

	public void execute(SQLTransaction tx) throws UnknownEntityException {
		String sql = getSQL();
		Object[] args = getArgs(t, tx);
		log.info(sql + " : " + Arrays.toString(args));
		tx.executeSql(sql, args);
	}

	public void execute(SQLTransaction tx, StatementCallback<?> callback)
			throws UnknownEntityException {
		String sql = getSQL();
		Object[] args = getArgs(t, tx);
		log.info(sql + " : " + Arrays.toString(args));
		tx.executeSql(sql, args, callback);
	}

	public String getSQL() {
		StringBuilder sql = new StringBuilder();
		sql.append("UPDATE ");
		sql.append(entity.getEntityName());
		sql.append(" SET ");
		String[] fieldnames = entity.getFieldnames();
		for (int i = 1; i < fieldnames.length; i++) {
			if (i > 1)
				sql.append(",");
			sql.append(fieldnames[i]);
			sql.append("=?");
		}
		sql.append(" WHERE ");
		sql.append(fieldnames[0]);
		sql.append("=?");
		return sql.toString();
	}

	public Object[] getArgs(T t, SQLTransaction tx)
			throws UnknownEntityException {
		DBEntityWriter writer = new DBEntityWriter(schema, tx,
				entity.getFieldnames());
		entity.getValues(t, writer);
		Object id = entity.getId(t);
		Object[] args = writer.getArgs();
		for (int i = 1; i < args.length; i++)
			args[i - 1] = args[i];
		args[args.length - 1] = id;
		return args;
	}

}
